package com.sijibao.gather.consumer.file;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sijibao.gather.consumer.ConsumerFileProcessor;

public class ConsumerFileProcessorImpl implements ConsumerFileProcessor
{

	private static final Logger logger = LoggerFactory
			.getLogger(ConsumerFileProcessorImpl.class);
	/**
	 * 日志文件目录
	 */
	private String path;
	private Map<String, String> fileNameMap;

	@Override
	public void destory()
	{
		logger.info("Consumer File Processor Begin Destroy...");
		if (fileNameMap != null)
		{
			fileNameMap.clear();
			fileNameMap = null;
		}
		logger.info("Consumer File Processor Destroy Success");
	}

	public Map<String, String> getFileNameMap()
	{
		return fileNameMap;
	}

	public void setFileNameMap(Map<String, String> fileNameMap)
	{
		this.fileNameMap = fileNameMap;
	}

	public void setPath(String path)
	{
		this.path = path;
	}

	public String getPath()
	{
		return path;
	}

	@Override
	public void writeLines(List<String> lines, String fileKey)
	{
		try
		{

			if (!getFileNameMap().containsKey(fileKey))
			{
				logger.error("fileNameMap中找不到fileKey={}对应的文件名", fileKey);
				return;
			}

			String fileName = getFileNameMap().get(fileKey);

			if (lines != null && (!lines.isEmpty()))
			{
				String fullPath = toFullPath(getPath(), fileName);
				logger.info("save to file:{} begin ...", fullPath);

				File file = new File(fullPath);
				if (!file.exists())
				{
					file.getParentFile().mkdirs();
					file.createNewFile();

					// 将上一天的文件压缩打包
					/*
					 * new Thread(new Runnable() {
					 * 
					 * @Override public void run() { try { String yesterdayPath
					 * = getFullPathYesterday( fileName); File yesterdayFile =
					 * new File(yesterdayPath); if (yesterdayFile.exists()) { if
					 * (toGZip(yesterdayPath)) yesterdayFile.delete(); } } catch
					 * (Exception e) { logger.error(e.getMessage(), e); }
					 * 
					 * } }).start();
					 */
				}

				write(lines, fileName, file);

				logger.info("save to file:{},line:{} success", fullPath,
						lines.size());
			}
		} catch (IOException e)
		{
			logger.error(e.getMessage(), e);
		}

	}

	private void write(List<String> lines, String fileName, File file)
	{
		BufferedWriter bw = null;

		try
		{
			bw = new BufferedWriter(new FileWriter(file, true));
			for (String line : lines)
			{
				bw.write(line);
				bw.newLine();
			}

			bw.flush();
		} catch (IOException e)
		{
			logger.error(e.getMessage(), e);
		} finally
		{
			if (bw != null)
			{
				try
				{
					bw.close();
				} catch (IOException e)
				{
					logger.error(e.getMessage(), e);
				}
			}
		}

	}

	private String toFullPath(String path, String fileName)
	{
		StringBuilder sb = new StringBuilder(path);
		sb.append("/");

		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		sb.append(format.format(new Date()));
		sb.append("/");
		sb.append(fileName);
		sb.append(".txt");
		return sb.toString();
	}

	private String getFullPathYesterday(String fileName)
	{
		StringBuilder sb = new StringBuilder(path);
		sb.append("/");
		sb.append(fileName);

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		sb.append(
				format.format(System.currentTimeMillis() - 24 * 3600 * 1000L));
		sb.append(".log");
		return sb.toString();
	}

	private synchronized boolean toGZip(String inFileName)
	{

		String outFileName = inFileName + ".gz";

		File outFile = new File(outFileName);
		if (outFile.exists())
			return true;

		FileInputStream in = null;
		GZIPOutputStream out = null;
		try
		{
			in = new FileInputStream(inFileName);
			out = new GZIPOutputStream(new FileOutputStream(outFile), 1024,
					true);
			byte[] buf = new byte[1024];
			int len = 0;

			while ((len = in.read(buf)) > 0)
			{
				out.write(buf, 0, len);
			}

			out.flush();

		} catch (IOException e)
		{
			logger.error(e.getMessage(), e);
			return false;
		} finally
		{

			if (in != null)
			{
				try
				{
					in.close();
				} catch (IOException e)
				{
					logger.error(e.getMessage(), e);
				}
			}

			if (out != null)
			{
				try
				{
					out.close();
				} catch (IOException e)
				{
					logger.error(e.getMessage(), e);
				}
			}

		}

		return true;
	}
}
